

#include <iostream>
#include <thread>
#include <chrono>
#include <string>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring>
#include <cerrno>
#include <filesystem>
#include <fstream>
class LogCleaner
{
public:
    static bool clearSystemCache()
    {
        try
        {
            std::ofstream ofs("/proc/sys/vm/drop_caches");
            if (!ofs)
            {
                //LOGE(CLEAR_CACHE) << "Failed to open drop_caches (need root privileges?)";
                return false;
            }

            ofs << "3";
            if (!ofs.good())
            {
                //LOGE(CLEAR_CACHE) << "Failed to write to drop_caches";
                return false;
            }

            return true;
        }
        catch (const std::exception &e)
        {
            //LOGE(CLEAR_CACHE) << "Exception: " << e.what();
            return false;
        }
        catch (...)
        {
            //LOGE(CLEAR_CACHE) << "Unknown exception";
            return false;
        }
    }

    static void
    Start(const std::string &log_dir, int keep_days)
    {
        std::thread([log_dir, keep_days]() { // 移除多余的参数传递
            while (true)
            {
                clearSystemCache(); // 清理系统缓存
                CleanNow(log_dir, keep_days);                        // 复用清理逻辑
                std::this_thread::sleep_for(std::chrono::hours(10)); // 每天执行一次
            }
        })
            .detach();
    }

    static void CleanNow(const std::string &log_dir, int keep_days)
    {
        time_t now = time(nullptr);
        DIR *dir = opendir(log_dir.c_str());

        if (!dir)
        {
            std::cerr << "Failed to open log directory: " << log_dir
                      << " - " << strerror(errno) << std::endl;
            return;
        }

        struct dirent *entry;
        while ((entry = readdir(dir)) != nullptr)
        {
            std::string filename = entry->d_name;
            if (filename == "." || filename == "..")
                continue;

            // 修复路径拼接（添加路径分隔符）
            std::string full_path = log_dir + "/" + filename;

            struct stat file_stat;
            if (stat(full_path.c_str(), &file_stat) != 0)
            {
                std::cerr << "Failed to stat: " << full_path
                          << " - " << strerror(errno) << std::endl;
                continue;
            }

            // 检查文件类型（只删除普通文件）
            if (!S_ISREG(file_stat.st_mode))
            {
                continue;
            }

            time_t file_time = file_stat.st_mtime;
            double diff_seconds = difftime(now, file_time);

            if (diff_seconds > keep_days * 86400.0)
            {
                if (std::remove(full_path.c_str()) != 0)
                {
                    std::cerr << "Delete failed: " << full_path
                              << " - " << strerror(errno) << std::endl;
                }
                else
                {
                    std::cout << "Deleted: " << full_path << std::endl;
                }
            }
        }
        closedir(dir);
    }
    ////////////

    static void CleanAllNow(const std::string &target_dir)
    {
        DIR *dir = opendir(target_dir.c_str());
        if (!dir)
        {
            std::cerr << "Failed to open directory: " << target_dir
                      << " - " << strerror(errno) << std::endl;
            return;
        }

        std::vector<std::string> entries;
        struct dirent *entry;
        while ((entry = readdir(dir)) != nullptr)
        {
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            {
                continue;
            }
            entries.push_back(entry->d_name);
        }
        closedir(dir);

        for (const auto &filename : entries)
        {
            std::string full_path = target_dir + "/" + filename;

            struct stat path_stat;
            if (lstat(full_path.c_str(), &path_stat) != 0)
            {
                std::cerr << "Failed to stat: " << full_path
                          << " - " << strerror(errno) << std::endl;
                continue;
            }

            if (S_ISDIR(path_stat.st_mode))
            {
                // 递归删除子目录
                CleanAllNow(full_path);

                // 删除空目录
                if (rmdir(full_path.c_str()) != 0)
                {
                    std::cerr << "Failed to remove directory: " << full_path
                              << " - " << strerror(errno) << std::endl;
                }
                else
                {
                    std::cout << "Removed directory: " << full_path << std::endl;
                }
            }
            else
            {
                // 删除文件
                if (std::remove(full_path.c_str()) != 0)
                {
                    std::cerr << "Delete failed: " << full_path
                              << " - " << strerror(errno) << std::endl;
                }
                else
                {
                    std::cout << "Deleted: " << full_path << std::endl;
                }
            }
        }
    }
    /////
};

/*#include <chrono>
#include <thread>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <cstdio>

class LogCleaner {
public:
    static void Start(const std::string& log_dir, int keep_days) {
        std::thread([log_dir, keep_days](int days) {
            while (true) {
                time_t now = time(nullptr);
                DIR *dir = opendir(log_dir.c_str());

                if (!dir) {
                    std::cerr << "Failed to open log directory: " << log_dir << std::endl;
                    std::this_thread::sleep_for(std::chrono::hours(24));
                    continue;
                }

                struct dirent *entry;
                while ((entry = readdir(dir)) != nullptr) {
                    std::string filename = entry->d_name;
                    if (filename == "." || filename == "..") continue;

                    size_t dot_pos = filename.find_last_of('.');
                    if (dot_pos != std::string::npos) {
                        std::string ext = filename.substr(dot_pos);
                        if (ext == ".INFO" || ext == ".WARNING" || ext == ".ERROR") {
                            std::string full_path = log_dir + "/" + filename;

                            struct stat file_stat;
                            if (stat(full_path.c_str(), &file_stat) == 0) {
                                time_t file_time = file_stat.st_mtime;
                                double diff_seconds = difftime(now, file_time);
                                if (diff_seconds > days * 86400) {
                                    if (std::remove(full_path.c_str()) == 0) {
                                        std::cout << "Deleted: " << full_path << std::endl;
                                    }
                                }
                            }
                        }
                    }
                }
                closedir(dir);
                std::this_thread::sleep_for(std::chrono::hours(24));
            }
        }, keep_days).detach();
    }
};*/

// C++17兼容的日志清理类
//  #include <chrono>
//  #include <filesystem>
//  #include <thread>

// class LogCleaner {
// public:
//     static void Start(int keep_days) {
//         std::thread([](int days) {
//             namespace fs = std::filesystem;
//             while (true) {
//                 auto now = fs::file_time_type::clock::now();
//                 for (auto& p : fs::directory_iterator(FLAGS_log_dir)) {
//                     if (p.path().extension() == ".INFO" ||
//                         p.path().extension() == ".WARNING" ||
//                         p.path().extension() == ".ERROR") {
//                         auto ftime = fs::last_write_time(p);
//                         if (now - ftime > std::chrono::hours(24 * days)) {
//                             fs::remove(p.path());
//                         }
//                     }
//                 }
//                 std::this_thread::sleep_for(std::chrono::hours(24));
//             }
//         }, keep_days).detach();
//     }
// };